<template>
  <div class="v-chart__wrap">
    <transition name="chart-fade">
      <el-card
        shadow="always"
        @click.native="handleTriggerClick"
        class="v-chart__trigger"
        v-show="triggerShow"
      >
        <div style="color:#fff">
          订单
          <span>[{{orders.length}}]</span>
        </div>
      </el-card>
    </transition>
    <transition name="chart-fade" @after-leave="afterChartLeave">
      <div class="v-chart__container" v-show="show" :class="show && 'open'" style="height:60%;">
        <div class="v-chart btt" :style="chatStyle">
          <div class="v-chart__header" @click="show = !show">
            {{chartHeader}}
            <span>- [{{orders.length}}]</span>
          </div>
          <div class="v-chart__body">
            <keep-alive>
              <v-component :is="activeTab" />
            </keep-alive>
          </div>
        </div>
      </div>
    </transition>

    <Modal
      title="接单信息"
      okText="接单"
      :loading="modalLoading"
      :visible.sync="modalVisible"
      :width="$V.size.sm"
      :onOk="handleSubmit"
      :onCancel="handleClose"
    >
      <ConfirmOrderForm :record="record" ref="orderForm" />
    </Modal>
  </div>
</template>
<script>
/* components
---------------------------------------------------------------- */
import List from './_comps/List'
import ConfirmOrderForm from '@/views/orders/maintenance-supplier/components/ConfirmOrderForm'

/* model
---------------------------------------------------------------- */
import { mapGetters } from 'vuex'
import event from '@/core/event'
import OrderTimer from '@/core/order'

/* api
---------------------------------------------------------------- */
import {
  getTakingOrderInfo,
  takeOrder
} from '@/api'

const TAB_CONFIG = [{ value: 'List', label: '订单列表' }]
export default {
  provide () {
    return {
      chat: this
    }
  },
  components: { List, ConfirmOrderForm },
  data () {
    return {
      show: false,
      triggerShow: true,
      visible: false,
      chatStyle: {},
      activeTab: 'List',
      tabs: TAB_CONFIG,
      numUsers: 0,
      onlineUsers: [],
      userList: [],
      chatMessageList: [],
      currentUser: null,

      openListWhenOrderChanged: true,

      orderLoading: false,

      // -------- Modal ----------
      record: {},
      modalVisible: false,
      modalLoading: false
      // -------- !Modal ----------
    }
  },
  computed: {
    ...mapGetters(['account', 'orders']),
    chartHeader () {
      const activeItem = TAB_CONFIG.find(it => it.value === this.activeTab)
      return activeItem ? activeItem.label : ''
    }
  },
  methods: {
    // ------------------------------  requests  ---------------------------------- */

    // ------------------------------  chat  ---------------------------------- */
    updateUserStatus () {
      let online
      this.userList = this.userList.map(it => {
        online = this.onlineUsers.find(user => user.userId === it.id)
        return {
          ...it,
          socketId: online && online.socketId,
          online: !!online
        }
      })
      // 用户刷新页面后导致socketId发生变化，如果在些之前已经打开窗口即currentUser有值，则会导致socketId不一致
      if (this.currentUser) {
        this.currentUser = this.userList.find(
          it => it.id === this.currentUser.id
        )
      }
    },

    /**
     * 通知订单
     */
    notifyUserJoined () {
      this.$notify({
        title: '订单通知',
        message: '您有新的订单啦',
        type: 'success'
      })
    },
    // ------------------------------ !chat  ---------------------------------- */

    handleTabClick (tab) {
      this.activeTab = tab.value
    },
    handleTriggerClick () {
      this.show = true
      this.triggerShow = false
    },
    afterChartLeave () {
      this.triggerShow = true
    },
    errorHandler () {
      return true
    },
    shouldNotify (prev, next) {
      if (next.length < prev.length) {
        return false
      }
      const prevIds = prev.map(it => it['orderId'])
      const nextIds = next.map(it => it['orderId'])

      return this.$difference(prevIds, nextIds).length > 0 || this.$difference(nextIds, prevIds).length > 0
    },

    // Modal
    // ------------------------------------------
    onClickTakeOrder (orderId) {
      this.getTakingOrderInfo(orderId, {
        onOk ({ data }) {
          this.record = {
            ...data,
            orderId
          }
          this.modalVisible = true
        }
      })
    },
    getTakingOrderInfo (id, { onOk, onError }) {
      return this.Catch(getTakingOrderInfo, {
        onOk,
        onError
      })('loading', id)
    },

    takeOrder (id, time) {
      return this.Catch(takeOrder, {
        onOk () {
          this.$message.success('接单成功')
          this.modalVisible = false
          // 立即重启timer
          OrderTimer.restart()
        },
        onError (err) {
          console.log(err)
        }
      })('modalLoading', id, time)
    },

    // 接单
    handleSubmit () {
      this.$refs.orderForm.submit((valid, values) => {
        if (valid) {
          const { orderId, appointmentTime } = values
          this.takeOrder(orderId, appointmentTime)
        }
      })
    },

    // 关闭modal清理数据
    handleClose () {
      this.modalVisible = false
    }
  },
  sockets: {
    connect () {},

    login ({ numUsers }) {
      this.numUsers = numUsers
    },

    userJoined ({ numUsers, username, onlineUsers }) {
      this.numUsers = numUsers
      this.onlineUsers = onlineUsers
      this.notifyUserJoined(username)
    },

    userOnline ({ onlineUsers, numUsers }) {
      this.numUsers = numUsers
      this.onlineUsers = onlineUsers
    },

    userLeft ({ numUsers, onlineUsers }) {
      this.numUsers = numUsers
      this.onlineUsers = onlineUsers
    },

    // 消息发送成功
    sendMessageSuccess ({ message }) {
      this.chatMessageList.push(message)
    },

    // 接收其它用户发送给我的消息
    receiveMessage ({ message }) {
      this.chatMessageList.push(message)
    }
  },
  created () {
    // 切换聊天主题
    this.$on('theme.change', theme => {
      let style = {
        backgroundImage: 'url(' + theme.bg + ')'
      }
      this.chatStyle = style
    })
  },

  mounted () {
    event.$on('getOrderListStart', () => {
      this.orderLoading = true
    })
    event.$on('getOrderListOk', ({ prev, next }) => {
      this.orderLoading = false
      let changed = this.shouldNotify(prev, next)
      if (changed) {
        this.notifyUserJoined()
        if (this.openListWhenOrderChanged) {
          this.show = true
        }
      }
    })
  },

  watch: {
    visible (val) {
      if (!val) {
        this.currentUser = null
      }
    }
  }
}
</script>
<style lang="scss">
.chat-modal {
  .v-Modal {
    background: url("~@/assets/chat/bg3.jpg");
    &__header {
      background: rgba(245, 245, 245, 0.7);
      padding: 16px 15px;
    }
    &__body {
      background: rgba(255, 255, 255, 0.9);
    }
  }
  .win-header {
    display: flex;
    align-items: center;
    > .el-avatar {
      margin-right: 10px;
    }
    > p {
      color: #444;
    }
  }
}
.v-chart__wrap {
  * {
    box-sizing: border-box;
  }
  .v-chart__trigger {
    position: absolute;
    right: 0;
    font-size: 14px;
    z-index: 9999;
    background: none;
    box-shadow: none;
    bottom: 0;
    width: 350px;
    height: 40px;
    background-color: rgba(0, 0, 0, 0.8);
    border-radius: 0;
    .el-card__body {
      padding: 0;
      line-height: 40px;
      justify-content: center;
    }
  }

  .v-chart__container {
    bottom: 0;
    position: fixed;
    bottom: 0;
    width: 350px;
    right: 0;
    z-index: 9999;
  }

  .el-card {
    cursor: pointer;
    border: none;
    box-shadow: none !important;
    &__body {
      display: flex;
      align-items: center;
      background: none;
      > img {
        width: 50px;
        border-radius: 50%;
        margin-right: 10px;
      }
      span {
        font-size: 15px;
      }
    }
  }
}

.v-chart {
  position: absolute;
  box-shadow: 1px 1px 50px rgba(0, 0, 0, 0.3);
  background-image: url("~@/assets/chat/bg2.jpg");
  background-size: cover;
  &.btt {
    right: 0;
    bottom: 0;
    top: 0;
    left: 0;
  }
  &__header {
    height: 40px;
    cursor: pointer;
    // background: #4caf50;
    background-color: rgba(0, 0, 0, 0.8);
    color: #fff;
    line-height: 40px;
    text-align: center;
  }
  &__body {
    height: calc(100% - 40px);
    background-color: rgba(255, 255, 255, 0.8);
  }
  &__footer {
    position: absolute;
    bottom: 0;
    width: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    display: flex;
    list-style-type: none;
  }
  &__tab {
    flex: 1;
    text-align: center;
    color: #fff;
    font-size: 14px;
    padding: 10px 0;
    cursor: pointer;
    &.active {
      color: #4caf50;
    }
  }
}

$directions: btt;

@mixin chart-animation($direction) {
  @keyframes #{$direction}-chart-in {
    0% {
      @if $direction == btt {
        transform: translate(0, 100%);
      }
    }

    100% {
      @if $direction == btt {
        transform: translate(0px, 0px);
      }
    }
  }

  @keyframes #{$direction}-chart-out {
    0% {
      @if $direction == btt {
        transform: translate(0, 0px);
      }
    }

    100% {
      @if $direction == btt {
        transform: translate(0px, 100%);
      }
    }
  }
}

@mixin animation-in($direction) {
  .open &.#{$direction} {
    animation: #{$direction}-chart-in 0.3s 1ms;
  }
}

@mixin animation-out($direction) {
  &.#{$direction} {
    animation: #{$direction}-chart-out 0.3s;
  }
}

@each $direction in $directions {
  @include chart-animation($direction);
}

.v-chart {
  @each $direction in $directions {
    @include animation-in($direction);
    @include animation-out($direction);
  }
}

@keyframes v-chart-fade-in {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

.chart-fade-enter-active {
  animation: v-chart-fade-in 0.3s;
}
.chart-fade-leave-active {
  animation: v-chart-fade-in 0.3s reverse;
}
</style>
